/*
 * Copyright 2006-2008 Michele Mostarda ( michele.mostarda@gmail.com ).
 * All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.graphnav.swing;

import org.graphnav.model.Filter;
import org.graphnav.model.FilteredGraphModel;
import org.graphnav.model.GraphModel;

import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Iterator;

/**
 * A panel showing a filter used to reduce nodes and arcs visibility.
 */
public class FilterPanel extends JPanel {

    protected class FieldsActionListener implements ActionListener, KeyListener, ItemListener {

        public void actionPerformed(ActionEvent e) {
            // Empty.
        }

        public void keyTyped(KeyEvent e) {
             //Empty.
        }

        public void keyPressed(KeyEvent e) {
            //Empty.
        }

        public void keyReleased(KeyEvent e) {
            validate();
        }

        private void validate() {
            if(fgm != null) { fgm.validate(); }
        }

        public void itemStateChanged(ItemEvent e) {
            String value =
                ( (JComboBox) e.getSource() ).getSelectedItem() == EMPTY_ELEM
                    ?
                ""
                    :
                ( (JComboBox) e.getSource() ).getSelectedItem().toString();
            if(e.getSource().equals(nodeValues)) {
                nodeFilterText.setText(value);
            } else {
                arcFilterText.setText(value);
            }
            validate();
        }
    }

    protected class TextFilter implements Filter {

        public void init() {}

        public void release() {}

        public boolean nodeIsVisible(GraphModel model, Node node) {
             return node.getDescription().contains(nodeFilterText.getText());
        }

        public boolean arcIsVisible(GraphModel model, Arc arc) {
            return arc.getDescription().contains(arcFilterText.getText());
        }
    }

    private static final String EMPTY_ELEM = "<None>";    

    private JLabel nodeFilterLabel = new JLabel("Node");

    private JLabel arcFilterLabel = new JLabel("Arc");

    private JTextField nodeFilterText = new JTextField();

    private JTextField arcFilterText =  new JTextField();

    private JComboBox nodeValues = new JComboBox();

    private JComboBox arcValues = new JComboBox();

    private FieldsActionListener fal = new FieldsActionListener();

    private FilteredGraphModel fgm = null;

    private TextFilter textFilter = new TextFilter();

    public FilterPanel() {
        nodeFilterText.addActionListener(fal);
        arcFilterText.addActionListener(fal);
        nodeFilterText.addKeyListener(fal);
        arcFilterText.addKeyListener(fal);

        setLayout(new GridLayout(2, 2, 10, 10));
        add(nodeFilterLabel);
        add(nodeFilterText);
        add(nodeValues);
        add(arcFilterLabel);
        add(arcFilterText);
        add(arcValues);
    }

    public FilteredGraphModel createFilteredGraphModel(GraphModel gm) {
        fgm = new FilteredGraphModel(gm, textFilter);
        populateCombos(gm);
        return fgm;
    }

    private void populateCombos(GraphModel gm) {
        nodeValues.removeItemListener(fal);
        arcValues.removeItemListener(fal);

        Iterator<Node> nodes = gm.nodes();
        nodeValues.removeAllItems();
        nodeValues.addItem(EMPTY_ELEM);
        while(nodes.hasNext()) {
            nodeValues.addItem(nodes.next().getDescription());
        }
        Iterator<Arc> arcs = gm.arcs();
        arcValues.removeAllItems();
        arcValues.addItem(EMPTY_ELEM);
        while(arcs.hasNext()) {
            arcValues.addItem(arcs.next().getDescription());
        }

        nodeValues.addItemListener(fal);
        arcValues.addItemListener(fal); 
    }

}
